/************************************************************************************************
 *   深圳市摩西尔电子有限公司 @版本所有@
 *
 *   此文件为 自定义鼠标菜单 控件
 *
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.03.03
 *      内容 : 所有代码
 *************************************************************************************************/

/* exported mc_get_menu_pot*/
/* exported mc_menu_custom_package */
/*****参数对象示例*********************************************************************************
* var options = {
*    target: null, // 开启自定义菜单的目标
*    hasIcon: true, //可选 是否需要图标
*    autoHide: true, //可选 是否自动隐藏右键菜单
*    linkClass: false, //是否使用外链样式,true使用外链样式(若选择false且同时设置css样式，则配置样式与css样式按优先级呈现);若选true,则可不用配置classes属性
*    directionRow: true, // 是否横向摆放项 (默认竖向)
*    LeftKeyTrigger: true, // 设置触发方式为鼠标左键 事件为鼠标抬起 (默认触发方式为鼠标右键按下)
*    menuItemBox : true, // 设置菜单项包裹标签 可方便添加布局 (默认不包裹),true时，菜单项包裹标签class将设置为menu_item_box
*    limitFn: mc_limit_menu, // 限制显示条件函数
*    beforeShow: mc_menu_beforeshow // 菜单栏显示前触发函数
*    beforeHide : mc_menu_hideback, // 菜单栏隐藏前触发函数
*    afterHide: mc_menu_hideback, // 菜单栏隐藏后触发函数
*    releaseNoClose: true, // 此项在菜单动作触发结束后不关闭菜单栏 默认关闭false /若此项为true菜单项releaseNoClose失效
*    undefineLocation: true // 此项开启，菜单栏只做显示切换动作，不定义鼠标事件
*    customPackage:null // 使用自定义包裹项 Function
*    childMemu : true // 是否存在二级菜单 默认不存在 是否绑定相关事件判断 可选
*
*    // 菜单项配置 无特殊标识默认为可为空属性
*    menu: {
*        items: [
*            {
*                icon: "icon-arrow-single-left", // 图标class/img图像路径 可选
*                title: "Prev", //  title属性
*                lang_id: "", // attr='lang_id'
*                content: "All", // 内容
*                className: "", 添加class属性
*                releaseNoClose: true, // 此项在当前菜单项动作触发结束后不关闭菜单栏
*                action: function (e, item) { //菜单项单击触发事件
*                    // console.log("选中上一个:",e,item);
*                },
*                keymap : "alt+1", // 快捷键（目前只支持：ctrl+  alt+  shift+  ）
*                iconPos : true, // 图标位置是否置后 默认置前 可选,
*                childMemu : [] // 二级菜单配置项 默认为空 可选
*            },
*            "-" // 分割线
*            "rowbox" // menuItemBox为true时生效 （此项下菜单为另一menu_item_box包裹 目的：多行每行多项菜单项）
*            ,,,
*        ]
*    }
*  };
*/

// 菜单显示时鼠标所在位置
var ui_menu_show_x = 0;
var ui_menu_show_y = 0;
var b_istouch = mc_istouch();

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建鼠标右键菜单 接收参数
 * 参数:
 *    @param { Promise<Object> } options 参数对象
 * 返回：
 *    无
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.03.03
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_custom_menu(options) {
    this.opt = this.extend(true, this.options, options);
    this.target = this.opt.target;

    // 初始化部分样式
    if (this.opt.classes && !this.opt.linkClass) {
        this.menu_box_class = this.extend(true, {
            "position": "absolute"
        }, this.opt.classes.menu_box);

        this.item_class = this.extend(true, {}, this.opt.classes.item.self);
        this.item_icon_class = this.extend(true, {
            display: "inline-block"
        }, this.opt.classes.item.icon);
        this.itemcom_class = this.extend(true, {}, this.opt.classes.item.content);

        this.hover_class = this.extend(true, {}, this.opt.classes.item.hover);

        this.separator_class = this.extend(true, {}, this.opt.classes.separator);
        this.keymap_class = this.extend(true, {
            "display": "inline-block",
            "height": "100%",
            "line-height": "24px",
            "float": "right"
        }, this.opt.classes.item.keymap);
    }
    this.init();
}

/*eslint complexity: ["error", 32]*/
// 创建标签
mc_custom_menu.prototype.init = function () {
    this.menu_box = document.createElement("div");

    this.attr(this.menu_box, {"unselectable": "on"});
    this.attr(this.menu_box, {"onselectstart": "return false;"});
    this.css(this.menu_box, {"-moz-user-select": "none"});
    this.css(this.menu_box, {"-webkit-user-select": "none"});

    if (!this.opt.linkClass) {
        this.css(this.menu_box, this.menu_box_class);
    }
    if (this.opt.directionRow) {
        this.addClass(this.menu_box,"mc_menu_row");
    }
    if (this.opt.childMemu) {
        this.css(this.menu_box, {"overflow": "initial"});
    }
    this.addClass(this.menu_box, "mc_menu_box");

    var i = 0;
    // 获取菜单项配置数组
    var items = this.opt.menu.items;
    // 菜单项盒子
    var item_box = document.createElement("div");
    var item_boxs = this.menu_box;

    if (this.opt.customPackage) {
        item_boxs = this.opt.customPackage.call(this,this);
    }


    // 循环创建菜单项
    if (items) {
        for (i = 0; i < items.length; i++) {
            var item;

            if ("-" === items[i]) {
                // 分隔线
                item = document.createElement("div");
                this.addClass(item, "mc_menu_separator");
                if (!this.opt.linkClass) {
                    this.css(item, this.separator_class);
                }
            } else if ("rowbox" === items[i] && this.opt.menuItemBox) {
                item_boxs.appendChild(item_box);
                item_box = document.createElement("div");
                continue;
            } else {
                item = create_menuItem(this,items[i]);
                var items_child = items[i].childMemu;

                // 二级菜单项
                if (items_child) {
                    var item_childbox = document.createElement("div");
                    var item_child;

                    this.addClass(item_childbox,"mc_childmenu_box");

                    for (var j = 0; j < items_child.length; j++) {
                        item_child = create_menuItem(this,items_child[j],true);
                        fn_event(j,this,item_child,items_child,true);
                        item_childbox.appendChild(item_child);
                    }
                    if (item_child) {
                        item.appendChild(item_childbox);
                        this.css(item,{"position": "relative"});
                    }
                }
                fn_event(i,this,item,items);
            }
            if (this.opt.menuItemBox) {
                this.addClass(item_box,"menu_item_box");
                item_box.appendChild(item);
            } else {
                item_boxs.appendChild(item);
            }
        }

        if (this.opt.menuItemBox) {
            item_boxs.appendChild(item_box);
        }
    }


    // eslint-disable-next-line no-unused-expressions
    (this.opt.target === document) ? (this.$("body")[0].appendChild(this.menu_box)) : (this.opt.target.appendChild(this.menu_box));
    this.hide();
    this.bind();
};

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    绑定事件 定义键盘按键
 * 参数:
 *     @param { Promise<Number> } i 循环到menu_item的次数
 *     @param { Promise<Object> } self 右键菜单
 *     @param { Promise<Object> } item 当前对象(菜单项)
 *     @param { Promise<Attr> } items 当前菜单子对象数组
 *     @param { Promise<Boolean> } b_child 是否为子菜单
 * 返回：
 *    无
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.03.03
 *      内容 : 所有代码
 ************************************************************************************************/
function fn_event(i,self,item,items,b_child) {
    var objEven = mc_get_event_type();
    var triggerEvenDown = objEven.triggerEvenDown;
    var triggerEvenMove = objEven.triggerEvenMove;
    var triggerEvenOut = objEven.triggerEvenOut;


    if (!self.opt.linkClass) {
        self.on(item, triggerEvenMove, function () {
            self.css(this, self.hover_class);
        });
        self.on(item, triggerEvenOut, function () {
            self.css(this, self.item_class);
        });
    }

    if (self.opt.LeftKeyTrigger) {
        if (b_istouch) {
            triggerEvenDown = "mouseup";
        } else {
            triggerEvenDown = "touchend";
        }
    }

    self.on(item, triggerEvenDown, function (e) {
        self.sb(e);
        items[i].action.call(self, e, items[i]);
        if (!self.opt.releaseNoClose && !e.target.getAttribute("noclose") && !e.target.parentNode.getAttribute("noclose")) {
            // 点击项关闭
            self.hide();
        }
    });

    if (self.opt.childMemu && !b_child) {
        self.on(item,"mouseover",function () {
            var obj_childMemu_list = document.getElementsByClassName("mc_childmenu_box");

            for (var index = 0; index < obj_childMemu_list.length; index++) {
                obj_childMemu_list[index].style.display = "none";
            }
            if (items[i].childMemu) {
                var obj_childMemu_box = item.getElementsByClassName("mc_childmenu_box")[0];
                var str_offsetl = obj_childMemu_box.parentNode.offsetWidth + 4 + "px";

                obj_childMemu_box.style.display = "block";
                obj_childMemu_box.style.left = str_offsetl;
            }
        });
    }

    if (items[i].keymap) {
        var keymap = items[i].keymap.split("+");

        self.on(document, "keydown", function (e) {
            var val = String.fromCharCode(e.keyCode).toLocaleLowerCase();

            switch (keymap[0]) {
            case "alt":
            {
                if (e.altKey) {
                    if (val === keymap[1].toLocaleLowerCase()) {
                        items[i].action.call(self, e, items[i]);
                    }
                }
                break;
            }
            case "shift":
            {
                if (e.shiftKey) {
                    if (val === keymap[1].toLocaleLowerCase()) {
                        items[i].action.call(self, e, items[i]);
                    }
                }
                break;
            }
            case "ctrl":
            {
                if (e.ctrlKey) {
                    if (val === keymap[1].toLocaleLowerCase()) {
                        items[i].action.call(self, e, items[i]);
                    }
                }
                break;
            }
             // no default
            }
        });
    }
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建菜单项标签
 * 参数:
 *     @param { Promise<Object> } self 右键菜单
 *     @param { Promise<Object> } obj_item 当前对象(菜单项)
 *     @param { Promise<Boolean> } b_child 是否为子菜单
 * 返回：
 *    @returns {Promise<Object> } 菜单项
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.10.12
 *      内容 : 所有代码
 ************************************************************************************************/
function create_menuItem(self,obj_item,b_child) {
    var item;
    var icon;

    item = document.createElement("div");
    if (b_child) {
        self.addClass(item, "mc_childmenu_item");
    } else {
        self.addClass(item, "mc_menu_item");
    }

    if (obj_item.title) {
        self.attr(item, {
            title: obj_item.title
        });
    }

    if (obj_item.lang_id) {
        self.attr(item,{
            lang_id: obj_item.lang_id
        });
    }

    // icon
    if (obj_item.icon) {
        if (-1 === obj_item.icon.indexOf(".")) {
            // iconFont
            icon = document.createElement("span");

            self.addClass(icon, "mc_menu_item_icon");
            self.addClass(icon, obj_item.icon);
            if (!self.opt.linkClass) {
                self.css(icon, self.item_icon_class);
            }
            if (!self.opt.hasIcon) {
                self.css(icon, {
                    width: 0
                });
            }
        } else {
            // img
            var image = self.opt.hasIcon ? "img" : "span";

            icon = document.createElement(image);
            self.addClass(icon, "mc_menu_item_icon");
            if (!self.opt.linkClass) {
                self.css(icon, self.item_icon_class);
            }
            if (!self.opt.hasIcon) {
                self.css(icon, {
                    width: 0
                });
            }
            self.attr(icon, {
                src: obj_item.icon
            });
        }
        if (icon && !obj_item.iconPos) {
            item.appendChild(icon);
        }
    }
    if (obj_item.content) {
        var con;

        if (b_child) {
            con = item;
        } else {
            con = document.createElement("span");
        }

        self.addClass(con, "mc_menu_itemcom");
        if (!self.opt.linkClass) {
            self.css(item, self.item_class);
            self.css(con, self.itemcom_class);
        }
        con.innerHTML = obj_item.content;
        if (!b_child) {
            item.appendChild(con);
        }
    }

    if (!self.opt.releaseNoClose && obj_item.releaseNoClose) {
        self.attr(item, {
            noclose: true
        });
    }

    if (obj_item.className) {
        self.addClass(item,obj_item.className);
    }

    // 快捷键标签
    if (obj_item.keymap) {
        var keymap = document.createElement("span");

        self.addClass(keymap, "mc_menu_keymap");
        keymap.innerHTML = obj_item.keymap;
        self.css(keymap, self.keymap_class);
        item.appendChild(keymap);
    }
    if (icon && obj_item.iconPos) {
        item.appendChild(icon);
    }
    return item;
}

// 显示
mc_custom_menu.prototype.show = function () {
    if (this.opt.beforeShow) {
        this.opt.beforeShow.call(this, this);
    }
    if (this.opt.directionRow) {
        this.css(this.menu_box, {
            "display": "flex"
        });
    } else {
        this.css(this.menu_box, {
            "display": "block"
        });
    }

    if (this.opt.undefineLocation) {
        return;
    }

    if (1 === arguments.length) {
        var l = 0, t = 0;
        var ui_clienX = 0;
        var ui_clienY = 0;

        if (b_istouch) {
            ui_clienX = arguments[0].clientX;
            ui_clienY = arguments[0].clientY;
        } else {
            ui_clienX = arguments[0].changedTouches[0].pageX;
            ui_clienY = arguments[0].changedTouches[0].pageY;
        }

        var obj_box = this.opt.target;
        /*获取当前鼠标右键按下后的位置，据此定义菜单显示的位置*/
        var rightedge = (obj_box === document) ? (document.documentElement.clientWidth - ui_clienX) : (obj_box.offsetWidth - ui_clienX);
        var bottomedge = (obj_box === document) ? (document.documentElement.clientHeight - ui_clienY) : (obj_box.offsetHeight - ui_clienY);

        ui_menu_show_x = ui_clienX;
        ui_menu_show_y = ui_clienY;
        if (rightedge < this.menu_box.offsetWidth) {
            l = ui_clienX - this.menu_box.offsetWidth;
        } else {
            l = ui_clienX;
        }
        if (bottomedge < this.menu_box.offsetHeight) {
            t = ui_clienY - this.menu_box.offsetHeight;
        } else {
            t = ui_clienY;
        }
        // var obj_boundrect = obj_box.getBoundingClientRect();

        // l = l + obj_boundrect.left + obj_box.scrollLeft;
        // t = t + obj_boundrect.top + obj_box.scrollTop;
        this.css(this.menu_box, {
            "left": l + "px",
            "top": t + "px"
        });

        // if (this.opt.afterShow) {
        //     this.opt.afterShow.call(this, this);
        // }
    }
};

// 隐藏
mc_custom_menu.prototype.hide = function () {
    if (this.opt.beforeHide) {
        this.opt.beforeHide.call(this, this);
    }
    this.css(this.menu_box, {
        "display": "none"
    });

    if (this.opt.afterHide) {
        this.opt.afterHide.call(this, this);
    }
};

// 事件绑定 禁用鼠标右击事件
mc_custom_menu.prototype.bind = function () {
    if (this.opt.undefineLocation) {
        return;
    }
    var self = this;
    var objEven = mc_get_event_type();
    var triggerEvenDown = objEven.triggerEvenDown;
    var triggerEvenMove = objEven.triggerEvenMove;
    var triggerEvenOut = objEven.triggerEvenOut;
    var eButton = 2;
    var bNocontextmenu = true;

    if (self.opt.LeftKeyTrigger) {
        if (b_istouch) {
            triggerEvenDown = "mouseup";
        } else {
            triggerEvenDown = "touchend";
        }
        eButton = 0;
        bNocontextmenu = false;
    }

    self.on(self.opt.target, "contextmenu", function (e) {
        var oEvent = e || event;

        if (bNocontextmenu) {
            nocontextmenu(oEvent);
        }
        return false;
    });

    self.on(self.opt.target, triggerEvenDown, function (e) {
        if (eButton === e.button || !b_istouch) {
            var b_show = "function" === typeof self.opt.limitFn ? self.opt.limitFn(e) : true;

            if (1 === b_show) {
                return;
            }
            if (b_show) {
                self.show(e);
            } else {
                self.hide();
            }
        }
    });

    // 禁止鼠标右键
    function nocontextmenu(ev) {
        if (ev.preventDefault) {
            ev.preventDefault();
        }
        ev.cancelBubble = true;
        ev.returnValue = false;
        return false;
    }

    self.on(document, triggerEvenDown, function (e) {
        if (eButton !== e.button && b_istouch) {
            // 点击其余位置关闭
            self.hide();
        }
    });

    self.on(self.menu_box, "click", function (e) {
        self.sb(e);
    });

    if (self.opt.autoHide) {
        var timer = null;

        self.on(self.menu_box, triggerEvenMove, function () {
            clearTimeout(timer);
        });
        self.on(self.menu_box, triggerEvenOut, function () {
            timer = setTimeout(function () {
                // 鼠标移出菜单关闭
                self.hide();
            }, 300);
        });
    }
};


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    类似jquery选择器，当传入字符串为html标签时为新建元素，否则为查找
 * 参数:
 *     @param { Promise<String> } q 选择器
 *     @param { Promise<Object> } o 父级
 * 返回：
 *    @return { Promise<Array> }
 *     obj 查找到的对象
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.03.03
 *      内容 : 所有代码
 ************************************************************************************************/
mc_custom_menu.prototype.$ = function (q, o) {
    var self = this;
    //查询表达式必须为字符串，并且不能为空。

    if ("string" !== typeof (q) || "" === q) {
        return [q];
    }
    var obj = [];
    var sObj = null;

    //使用空格分割，只处理第一个表达式
    var ss = q.split(" ");
    //获取属性
    var attr = "";
    var s = ss[0].split(":")[0];

    $_reduce_complexity(o,obj,ss,attr,s,sObj);

    if (attr) {
        //: 筛选属性匹配
        var arr_attr_l = [];

        for (var attr_item = 0; attr_item < obj.length; attr_item++) {
            if (obj[attr_item][attr]) {
                arr_attr_l.push(obj[attr_item]);
            }
        }
        obj = arr_attr_l;
    }

    if (1 < ss.length) {
        //递归处理表达式后续内容
        //父元素为已获取的所有元素
        var arr_ss_l = [];

        for (var ss_item = 0; ss_item < obj.length; ss_item++) {
            //var ll = arguments.callee(q.substr(ss[0].length + 1), obj[i]);
            var ll = self.$.call(self, q.substr(ss[0].length + 1), obj[ss_item]);

            if (ll.tagName) {
                arr_ss_l.push(ll);
            } else {
                for (var j = 0; j < ll.length; j++) {
                    arr_ss_l.push(ll[j]);
                }
            }
        }
        obj = arr_ss_l;
    }

    if (sObj && 1 === ss.length) {
        //当为ID选择器时，直接返回对象。
        obj = sObj;
        if (obj) {
            obj.length = 1;
        }
    } else {
        //去除数组中重复元素
        var l = [];

        for (var item = 0; item < obj.length; item++) {
            obj[item].$isAdd = false;
        }
        for (var i = 0; i < obj.length; i++) {
            if (!obj[i].$isAdd) {
                obj[i].$isAdd = true;
                l.push(obj[i]);
            }
        }
        obj = l;
    }
    return obj;
};

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    拆分减小$的复杂度
 * 参数:
 *     @param { Promise<Object> } o 父级
 *     @param { Promise<Array> } obj []
 *     @param { Promise<Array> } ss 第一个表达式
 *     @param { Promise<String> } attr 属性
 *     @param { Promise<String> } s 标签名
 *     @param { Promise<Null> } sObj null
 * 返回：
 *    无
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.03.03
 *      内容 : 所有代码
 ************************************************************************************************/
function $_reduce_complexity(o,obj,ss,attr,s,sObj) {
    if (s !== ss[0]) {
        attr = ss[0].split(":")[1];
    }
    var val = s.split("[")[0];

    if (val !== s) {
        val = s.split("[")[1].replace(/[",\]]/g, "");
    } else {
        val = "";
    }
    s = s.split("[")[0];

    //当父对象不存在时，使用document;
    o = o || document;
    switch (s.charAt(0)) {
    case "#":
        //ID选择器
        sObj = document.getElementById(s.substr(1));
        if (sObj) {
            obj.push(sObj);
        }
        break;
    case ".":
        //类选择器
        var l = o.getElementsByTagName("*");
        var c = s.substr(1);

        for (var i = 0; i < l.length; i++) {
            if (-1 !== l[i].className.search("\\b" + c + "\\b")) {
                obj.push(l[i]);
            }
        }
        break;
    default:
        //根据tag获取元素
        obj = o.getElementsByTagName(s);
        break;
    }
    if (val) {
        //[t=val]筛选属性匹配
        var arr_l = [];
        var a = val.split("=");

        for (var j = 0; j < obj.length; j++) {
            if (2 === a.length && obj[j][a[0]] === a[1]) {
                arr_l.push(obj[j]);
            }
        }
        obj = arr_l;
    }
}

// 事件监听
mc_custom_menu.prototype.on = function (element, eventName, handler) {
    if (element.addEventListener) {
        element.addEventListener(eventName, handler, false);
    } else if (element.attachEvent) {
        //这里用了对象检测方法判断浏览器,最后的参数false表示事件在捕获阶段,若为true则表示在冒泡阶段
        element.attachEvent("on" + eventName, handler);
    } else {
        element["on" + eventName] = handler;
    }
};

// 默认配置
mc_custom_menu.prototype.options = {
    target: document,
    menu: {
        items: [
            {
                icon: "",
                content: "\u83dc\u5355\u98791",
                action: function () {
                    // alert(item.content);
                }
            },
            "-",
            {
                icon: "",
                content: "\u83dc\u5355\u98792",
                action: function () {
                    // alert("====>" + item.content);
                }
            }
        ]
    }
};

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    合并对象的方法
 * 参数:
 *    @param { Promise<Boolean> } flag 是否合并
 *    @param { Promise<Object> } destination 新增合并的对象
 *    @param { Promise<Object> } source 之前合并的对象
 * 返回：
 *    @return { Promise<Object> } obj
 *    @return { Promise<Object>} destination 合并之后的对象
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.03.03
 *      内容 : 所有代码
 ************************************************************************************************/
mc_custom_menu.prototype.extend = function (flag, destination, source) {
    if (flag) {
        var obj = {};

        for (var property in destination) {
            if (Object.prototype.hasOwnProperty.call(destination, property)) {
                obj[property] = destination[property];
            }
        }
        for (var property_s in source) {
            if (Object.prototype.hasOwnProperty.call(source, property_s)) {
                obj[property_s] = source[property_s];
            }
        }
        return obj;
    }

    for (var property_source in source) {
        if (Object.prototype.hasOwnProperty.call(source, property_source)) {
            destination[property_source] = source[property_source];
        }
    }
    return destination;
};

// 对元素行间样式的操作
mc_custom_menu.prototype.css = function () {
    var arg = arguments;
    var i = 0;
    var len = arg.length;

    if (2 === len) {
        var obj = arg[0];
        var value = arg[1];

        if (this.isArray(obj)) {
            for (i = 0; i < obj.length; i++) {
                if ("string" === typeof value) {
                    if (obj[i].currentStyle) {
                        //IE
                        return this.fixed(obj[i].currentStyle[value], 1);
                    } else if (window.getComputedStyle) {
                        //非IE
                        value = value.replace(/([A-Z])/g, "-$1");
                        value = value.toLowerCase();
                        return this.fixed(document.defaultView.getComputedStyle(obj[i], null)[value], 1);
                    }
                } else if ("object" === typeof value) {
                    for (var j in value) {
                        if (Object.prototype.hasOwnProperty.call(value, j)) {
                            obj[i].style[j] = value[j];
                        }
                    }
                }
            }
        } else {
            if ("string" === typeof value) {
                if (obj.currentStyle) {
                    //IE
                    return this.fixed(obj.currentStyle[value], 1);
                } else if (window.getComputedStyle) {
                    //非IE
                    value = value.replace(/([A-Z])/g, "-$1");
                    value = value.toLowerCase();
                    return this.fixed(document.defaultView.getComputedStyle(obj, null)[value], 1);
                }
            } else if ("object" === typeof value) {
                for (var j_key in value) {
                    if (Object.prototype.hasOwnProperty.call(value, j_key)) {
                        obj.style[j_key] = value[j_key];
                    }
                }
            }
        }
    }
    return true;
};

// 对元素属性的操作
mc_custom_menu.prototype.attr = function () {
    var arg = arguments;
    var i = 0;
    var len = arg.length;

    if (2 === len) {
        var obj = arg[0], value = arg[1];

        if (this.isArray(obj)) {
            for (i = 0; i < obj.length; i++) {
                //console.log(obj[i]);
                if ("string" === typeof value) {
                    if (0 !== value.length) {
                        return obj[i].getAttribute(value);
                    }
                    return obj[i].attributes;
                } else if ("object" === typeof value) {
                    for (var j in value) {
                        if (Object.prototype.hasOwnProperty.call(value, j)) {
                            obj[i].setAttribute(j, value[j]);
                        }
                    }
                }
            }
        } else {
            if ("string" === typeof value) {
                if (0 !== value.length) {
                    return obj.getAttribute(value);
                }
            } else if ("object" === typeof value) {
                for (var j_key in value) {
                    if (Object.prototype.hasOwnProperty.call(value, j_key)) {
                        obj.setAttribute(j_key, value[j_key]);
                    }
                }
            }
        }
    }
    return true;
};

//  判断参数是否为数组
mc_custom_menu.prototype.isArray = function (obj) {
    ///	<summary>
    ///		确定传递的参数是否为数组。
    ///	</summary>
    ///	<param name="obj" type="Object">要测试其是否为数组的对象。</param>
    ///	<returns type="Boolean">如果该参数为函数，则为 true；否则为 false。</returns>
    var result;

    try {
        result = "[object Array]" === toString.call(obj);
    } catch (Exception) {
        result = obj instanceof Array;
    }
    return result;
};

// 阻止事件冒泡的通用函数
mc_custom_menu.prototype.sb = function (e) {
    // 如果传入了事件对象，那么就是非ie浏览器
    if (e && e.stopPropagation) {
        //因此它支持W3C的stopPropagation()方法
        e.stopPropagation();
    } else {
        //否则我们使用ie的方法来取消事件冒泡
        window.event.cancelBubble = true;
    }
};

// 判断对象是否拥有某个class
mc_custom_menu.prototype.hasClass = function (obj, cls) {
    return obj.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
};

// 新增class
mc_custom_menu.prototype.addClass = function (obj, cls) {
    if (this.isArray(obj)) {
        for (var i = 0; i < obj.length; i++) {
            if (!this.hasClass(obj[i], cls)) {
                obj[i].className += " " + cls;
            }
        }
    } else {
        if (!this.hasClass(obj, cls)) {
            obj.className += " " + cls;
        }
    }
    obj.className = obj.className.trim();
};

// 移除class
mc_custom_menu.prototype.removeClass = function (obj, cls) {
    if (this.isArray(obj)) {
        for (var i = 0; i < obj.length; i++) {
            if (this.hasClass(obj[i], cls)) {
                var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");

                obj[i].className = obj[i].className.replace(reg, " ");
            }
        }
    } else {
        if (this.hasClass(obj, cls)) {
            var str_reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");

            obj.className = obj.className.replace(str_reg, " ");
        }
    }
};

// 若元素已有样式则移除样式，若没有该样式则添加样式
mc_custom_menu.prototype.toggleClass = function (obj, cls) {
    if (this.isArray(obj)) {
        for (var i = 0; i < obj.length; i++) {
            if (this.hasClass(obj[i], cls)) {
                this.removeClass(obj[i], cls);
            } else {
                this.addClass(obj[i], cls);
            }
        }
    } else {
        if (this.hasClass(obj, cls)) {
            this.removeClass(obj, cls);
        } else {
            this.addClass(obj, cls);
        }
    }
};

// 检查某个对象是否为空(不包含任何属性)
mc_custom_menu.prototype.isEmptyObject = function (obj) {
    ///	<summary>
    ///		检查某个对象是否为空(不包含任何属性)。
    ///	</summary>
    ///	<param name="obj" type="Object">
    ///		将检查其是否为空的对象。
    ///	</param>
    ///	<returns type="Boolean" />

    for (var name in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, name)) {
            return false;
        }
    }
    return true;
};

// 获取显示时鼠标所在位置
function mc_get_menu_pot() {
    return {x: ui_menu_show_x,y: ui_menu_show_y};
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    判断是否为PC端
 * 参数:
 *    无
 * 返回：
 *    @return { Promise<Boolean> }
 *    true PC端
 *    false 移动端
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2019.12.19
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_istouch() {
    var flag = true;

    if ("ontouchstart" in window) {
        flag = false;
    }
    return flag;
}

// 区分移动端|PC端 事件类型
function mc_get_event_type() {
    var obj = {};

    if (b_istouch) {
        obj.triggerEvenDown = "mousedown";
        obj.triggerEvenMove = "mouseover";
        obj.triggerEvenOut = "mouseout";
    } else {
        obj.triggerEvenDown = "touchstart";
        obj.triggerEvenMove = "touchmove";
        obj.triggerEvenOut = "touchend";
    }
    return obj;
}

// 自定义包裹函数
function mc_menu_custom_package(obj) {
    var item_boxs = document.createElement("div");

    obj.addClass(item_boxs,"mc_item_boxs");
    obj.menu_box.appendChild(item_boxs);
    return item_boxs;
}
